home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src / image.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-13  |  18.4 KB  |  618 lines

  1. /* $Id: image.c,v 1.9 1997/02/09 20:05:03 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.2
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: image.c,v $
  26.  * Revision 1.9  1997/02/09 20:05:03  brianp
  27.  * new arguments for gl_pixel_addr_in_image()
  28.  *
  29.  * Revision 1.8  1997/02/09 18:52:53  brianp
  30.  * added GL_EXT_texture3D support
  31.  *
  32.  * Revision 1.7  1997/01/09 21:25:54  brianp
  33.  * initialize image reference count to zero
  34.  *
  35.  * Revision 1.6  1996/11/13 03:58:31  brianp
  36.  * fixed undefined "format" variable in gl_unpack_image()
  37.  *
  38.  * Revision 1.5  1996/11/10 17:48:03  brianp
  39.  * check if format is GL_DEPTH_COMPONENT or GL_STENCIL_COMPONENT
  40.  *
  41.  * Revision 1.4  1996/11/06 04:23:01  brianp
  42.  * changed gl_unpack_image() components argument to srcFormat
  43.  *
  44.  * Revision 1.3  1996/09/27 01:27:10  brianp
  45.  * removed unused variables
  46.  *
  47.  * Revision 1.2  1996/09/26 22:35:10  brianp
  48.  * fixed a few compiler warnings from IRIX 6 -n32 and -64 compiler
  49.  *
  50.  * Revision 1.1  1996/09/13 01:38:16  brianp
  51.  * Initial revision
  52.  *
  53.  */
  54.  
  55.  
  56. #include <assert.h>
  57. #include <stdlib.h>
  58. #include <string.h>
  59. #include "image.h"
  60. #include "macros.h"
  61. #include "pixel.h"
  62. #include "types.h"
  63.  
  64.  
  65.  
  66.  
  67. /*
  68.  * Flip the 8 bits in each byte of the given array.
  69.  */
  70. void gl_flip_bytes( GLubyte *p, GLuint n )
  71. {
  72.    register GLuint i, a, b;
  73.  
  74.    for (i=0;i<n;i++) {
  75.       b = (GLuint) p[i];
  76.       a = ((b & 0x01) << 7) |
  77.       ((b & 0x02) << 5) |
  78.       ((b & 0x04) << 3) |
  79.       ((b & 0x08) << 1) |
  80.       ((b & 0x10) >> 1) |
  81.       ((b & 0x20) >> 3) |
  82.       ((b & 0x40) >> 5) |
  83.       ((b & 0x80) >> 7);
  84.       p[i] = (GLubyte) a;
  85.    }
  86. }
  87.  
  88.  
  89. /*
  90.  * Flip the order of the 2 bytes in each word in the given array.
  91.  */
  92. void gl_swap2( GLushort *p, GLuint n )
  93. {
  94.    register GLuint i;
  95.  
  96.    for (i=0;i<n;i++) {
  97.       p[i] = (p[i] >> 8) | ((p[i] << 8) & 0xff00);
  98.    }
  99. }
  100.  
  101.  
  102.  
  103. /*
  104.  * Flip the order of the 4 bytes in each word in the given array.
  105.  */
  106. void gl_swap4( GLuint *p, GLuint n )
  107. {
  108.    register GLuint i, a, b;
  109.  
  110.    for (i=0;i<n;i++) {
  111.       b = p[i];
  112.       a =  (b >> 24)
  113.     | ((b >> 8) & 0xff00)
  114.     | ((b << 8) & 0xff0000)
  115.     | ((b << 24) & 0xff000000);
  116.       p[i] = a;
  117.    }
  118. }
  119.  
  120.  
  121.  
  122.  
  123. /*
  124.  * Return the size, in bytes, of the given GL datatype.
  125.  * Return 0 if GL_BITMAP.
  126.  * Return -1 if invalid type enum.
  127.  */
  128. GLint gl_sizeof_type( GLenum type )
  129. {
  130.    switch (type) {
  131.       case GL_BITMAP:
  132.      return 0;
  133.       case GL_UNSIGNED_BYTE:
  134.          return sizeof(GLubyte);
  135.       case GL_BYTE:
  136.      return sizeof(GLbyte);
  137.       case GL_UNSIGNED_SHORT:
  138.      return sizeof(GLushort);
  139.       case GL_SHORT:
  140.      return sizeof(GLshort);
  141.       case GL_UNSIGNED_INT:
  142.      return sizeof(GLuint);
  143.       case GL_INT:
  144.      return sizeof(GLint);
  145.       case GL_FLOAT:
  146.      return sizeof(GLfloat);
  147.       default:
  148.          return -1;
  149.    }
  150. }
  151.  
  152.  
  153.  
  154. /*
  155.  * Return the number of components in a GL enum pixel type.
  156.  * Return -1 if bad format.
  157.  */
  158. GLint gl_components_in_format( GLenum format )
  159. {
  160.    switch (format) {
  161.       case GL_COLOR_INDEX:
  162.       case GL_STENCIL_INDEX:
  163.       case GL_DEPTH_COMPONENT:
  164.       case GL_RED:
  165.       case GL_GREEN:
  166.       case GL_BLUE:
  167.       case GL_ALPHA:
  168.       case GL_LUMINANCE:
  169.          return 1;
  170.       case GL_LUMINANCE_ALPHA:
  171.      return 2;
  172.       case GL_RGB:
  173.      return 3;
  174.       case GL_RGBA:
  175.      return 4;
  176.       default:
  177.          return -1;
  178.    }
  179. }
  180.  
  181.  
  182. /*
  183.  * Return the address of a pixel in an image (actually a volume).
  184.  * Pixel unpacking/packing parameters are observed according to 'packing'.
  185.  * Input:  image - start of image data
  186.  *         width, height - size of image
  187.  *         format - image format
  188.  *         type - pixel component type
  189.  *         packing - GL_TRUE = use packing params
  190.  *                   GL_FALSE = use unpacking params.
  191.  *         img - which image in the volume (0 for 2-D images)
  192.  *         row, column - location of pixel in the image
  193.  * Return:  address of pixel at (image,row,column) in image or NULL if error.
  194.  */
  195. GLvoid *gl_pixel_addr_in_image( struct gl_pixelstore_attrib *packing,
  196.                                 const GLvoid *image, GLsizei width,
  197.                                 GLsizei height, GLenum format, GLenum type,
  198.                                 GLint img, GLint row, GLint column )
  199. {
  200.    GLint bytes_per_comp;   /* bytes per component */
  201.    GLint comp_per_pixel;   /* components per pixel */
  202.    GLint comps_per_row;    /* components per row */
  203.    GLint pixels_per_row;   /* pixels per row */
  204.    GLint bytes_per_image;
  205.    GLint rows_per_image;
  206.    GLint alignment;        /* 1, 2 or 4 */
  207.    GLint skiprows;
  208.    GLint skippixels;
  209.    GLint skipimages;       /* for 3-D */
  210.    GLubyte *pixel_addr;
  211.  
  212.    /* Compute bytes per component */
  213.    bytes_per_comp = gl_sizeof_type( type );
  214.    if (bytes_per_comp<0) {
  215.       return NULL;
  216.    }
  217.  
  218.    /* Compute number of components per pixel */
  219.    comp_per_pixel = gl_components_in_format( format );
  220.    if (comp_per_pixel<0) {
  221.       return NULL;
  222.    }
  223.  
  224.    alignment = packing->Alignment;
  225.    if (packing->RowLength>0) {
  226.       pixels_per_row = packing->RowLength;
  227.    }
  228.    else {
  229.       pixels_per_row = width;
  230.    }
  231.    if (packing->ImageHeight>0) {
  232.       rows_per_image = packing->ImageHeight;
  233.    }
  234.    else {
  235.       rows_per_image = height;
  236.    }
  237.    skiprows = packing->SkipRows;
  238.    skippixels = packing->SkipPixels;
  239.    skipimages = packing->SkipImages;
  240.  
  241.    if (type==GL_BITMAP) {
  242.       /* BITMAP data */
  243.       GLint bytes_per_row;
  244.  
  245.       bytes_per_row = alignment
  246.                     * CEILING( comp_per_pixel*pixels_per_row, 8*alignment );
  247.  
  248.       bytes_per_image = bytes_per_row * rows_per_image;
  249.  
  250.       pixel_addr = (GLubyte *) image
  251.                  + (skipimages + img) * bytes_per_image
  252.                  + (skiprows + row) * bytes_per_row
  253.                  + (skippixels + column) / 8;
  254.    }
  255.    else {
  256.       /* Non-BITMAP data */
  257.  
  258.       if (bytes_per_comp>=alignment) {
  259.      comps_per_row = comp_per_pixel * pixels_per_row;
  260.       }
  261.       else {
  262.          GLint bytes_per_row = bytes_per_comp * comp_per_pixel
  263.                              * pixels_per_row;
  264.  
  265.      comps_per_row = alignment / bytes_per_comp
  266.                        * CEILING( bytes_per_row, alignment );
  267.       }
  268.  
  269.       bytes_per_image = bytes_per_comp * comps_per_row * rows_per_image;
  270.  
  271.       /* Copy/unpack pixel data to buffer */
  272.       pixel_addr = (GLubyte *) image
  273.                  + (skipimages + img) * bytes_per_image
  274.                  + (skiprows + row) * bytes_per_comp * comps_per_row
  275.                  + (skippixels + column) * bytes_per_comp * comp_per_pixel;
  276.    }
  277.  
  278.    return (GLvoid *) pixel_addr;
  279. }
  280.  
  281.  
  282.  
  283. /*
  284.  * Unpack a 2-D image from user-supplied address, returning a pointer to
  285.  * a new gl_image struct.
  286.  * This function is always called by a higher-level unpack function such
  287.  * as gl_unpack_texsubimage() or gl_unpack_bitmap().
  288.  *
  289.  * Input:  width, height - size in pixels
  290.  *         srcFormat - format of incoming pixel data, ignored
  291.  *                      if srcType and destType is BITMAP.
  292.  *         srcType - GL_UNSIGNED_BYTE .. GL_FLOAT
  293.  *         destType - store image as GL_UNSIGNED_BYTE, GL_FLOAT, or GL_BITMAP.
  294.  *                    if GL_UNSIGNED_BYTE, srctype must be GL_UNSIGNED_BYTE.
  295.  *                    if GL_BITMAP, srctype must be GL_BITMAP.
  296.  *         interleave - if TRUE, srctype and destType must be GL_UNSIGNED_BYTE
  297.  *         pixels - pointer to unpacked image.
  298.  */
  299. struct gl_image *gl_unpack_image( GLcontext *ctx,
  300.                                   GLint width, GLint height,
  301.                                   GLenum srcFormat, GLenum srcType,
  302.                                   GLenum destType,
  303.                                   const GLvoid *pixels,
  304.                                   GLboolean interleave )
  305.    return gl_unpack_image3D(ctx, width, height, 1,
  306.                             srcFormat, srcType, destType, pixels, interleave);
  307. }
  308.  
  309.  
  310.  
  311. /* 
  312.  * Unpack a 2-D/3-D image from user-supplied address, returning a pointer to
  313.  * a new gl_image struct.
  314.  * This function is always called by a higher-level unpack function such
  315.  * as gl_unpack_texsubimage() or gl_unpack_bitmap().
  316.  *
  317.  * Input:  width, height, depth - size in pixels
  318.  *         srcFormat - format of incoming pixel data, ignored
  319.  *                      if srcType and destType is BITMAP.
  320.  *         srcType - GL_UNSIGNED_BYTE .. GL_FLOAT
  321.  *         destType - store image as GL_UNSIGNED_BYTE, GL_FLOAT, or GL_BITMAP.
  322.  *                    if GL_UNSIGNED_BYTE, srctype must be GL_UNSIGNED_BYTE.
  323.  *                    if GL_BITMAP, srctype must be GL_BITMAP.
  324.  *         interleave - if TRUE, srctype and destType must be GL_UNSIGNED_BYTE
  325.  *         pixels - pointer to unpacked image.
  326.  */
  327. struct gl_image *gl_unpack_image3D( GLcontext *ctx,
  328.                                     GLint width, GLint height, GLint depth,
  329.                                     GLenum srcFormat, GLenum srcType,
  330.                                     GLenum destType,
  331.                                     const GLvoid *pixels,
  332.                                     GLboolean interleave )
  333. {
  334.    GLint components;
  335.  
  336.    components = gl_components_in_format( srcFormat );
  337.  
  338.    if (srcType==GL_BITMAP || destType==GL_BITMAP) {
  339.       struct gl_image *image;
  340.       GLint bytes, i, width_in_bytes, d;
  341.       GLubyte *buffer, *dst;
  342.       assert( srcType==GL_BITMAP );
  343.       assert( destType==GL_BITMAP );
  344.  
  345.       /* Alloc dest storage */
  346.       bytes = ((width+7)/8 * height) * depth;
  347.       if (bytes>0 && pixels!=NULL) {
  348.          buffer = (GLubyte *) malloc( bytes );
  349.          if (!buffer) {
  350.             return NULL;
  351.          }
  352.          /* Copy/unpack pixel data to buffer */
  353.          width_in_bytes = CEILING( width, 8 );
  354.          dst = buffer;
  355.          for (d=0; d<depth; d++) {
  356.             for (i=0; i<height; i++) {
  357.                GLvoid *src = gl_pixel_addr_in_image( &ctx->Unpack, pixels,
  358.                                                      width, height,
  359.                                                      GL_COLOR_INDEX, srcType,
  360.                                                      d, i, 0 );
  361.                if (!src) {
  362.                   free(buffer);
  363.                   return NULL;
  364.                }
  365.                MEMCPY( dst, src, width_in_bytes );
  366.                dst += width_in_bytes;
  367.             }
  368.          }
  369.          /* Bit flipping */
  370.          if (ctx->Unpack.LsbFirst) {
  371.             gl_flip_bytes( buffer, bytes );
  372.          }
  373.       }
  374.       else {
  375.          /* a 'null' bitmap */
  376.          buffer = NULL;
  377.       }
  378.  
  379.       image = (struct gl_image *) malloc( sizeof(struct gl_image) );
  380.       if (image) {
  381.          image->Width = width;
  382.          image->Height = height;
  383.          image->Depth = depth;
  384.          image->Components = 0;
  385.          image->Format = GL_COLOR_INDEX;
  386.          image->Type = GL_BITMAP;
  387.          image->Interleaved = GL_FALSE;
  388.          image->Data = buffer;
  389.          image->RefCount = 0;
  390.       }
  391.       else {
  392.          free( buffer );
  393.          return NULL;
  394.       }
  395.       return image;
  396.    }
  397.    else if (srcFormat==GL_DEPTH_COMPONENT) {
  398.       /* TODO: pack as GLdepth values (GLushort or GLuint) */
  399.  
  400.    }
  401.    else if (srcFormat==GL_STENCIL_INDEX) {
  402.       /* TODO: pack as GLstencil (GLubyte or GLushort) */
  403.  
  404.    }
  405.    else if (destType==GL_UNSIGNED_BYTE) {
  406.       struct gl_image *image;
  407.       GLint width_in_bytes;
  408.       GLubyte *buffer, *dst;
  409.       GLint i, d;
  410.       assert( srcType==GL_UNSIGNED_BYTE );
  411.  
  412.       width_in_bytes = width * components * sizeof(GLubyte);
  413.       buffer = malloc( height * width_in_bytes * depth );
  414.       if (!buffer) {
  415.          return NULL;
  416.       }
  417.       /* Copy/unpack pixel data to buffer */
  418.       dst = buffer;
  419.       for (d=0; d<depth; d++ ) {
  420.          for (i=0;i<height;i++) {
  421.             GLubyte *src = (GLubyte *) gl_pixel_addr_in_image( &ctx->Unpack,
  422.                            pixels, width, height, srcFormat, srcType, d, i, 0 );
  423.             if (!src) {
  424.                free(buffer);
  425.                return NULL;
  426.             }
  427.             if (interleave) {
  428.                GLint j, k;
  429.                for (j=0;j<width;j++) {
  430.                   for (k=0;k<components;k++) {
  431.                      dst[k*width+j] = src[j*components+k];
  432.                   }
  433.                }
  434.             }
  435.             else {
  436.                MEMCPY( dst, src, width_in_bytes );
  437.             }
  438.             dst += width_in_bytes;
  439.          }
  440.       }
  441.  
  442.       if (ctx->Unpack.LsbFirst) {
  443.          gl_flip_bytes( buffer, height * width_in_bytes * depth );
  444.       }
  445.  
  446.       image = (struct gl_image *) malloc( sizeof(struct gl_image) );
  447.       if (image) {
  448.          image->Width = width;
  449.          image->Height = height;
  450.          image->Depth = depth; 
  451.          image->Components = components;
  452.          image->Format = srcFormat;
  453.          image->Type = GL_UNSIGNED_BYTE;
  454.          image->Interleaved = interleave;
  455.          image->Data = buffer;
  456.       }
  457.       else {
  458.          free( buffer );
  459.          return NULL;
  460.       }
  461.       return image;
  462.    }
  463.    else if (destType==GL_FLOAT) {
  464.       struct gl_image *image;
  465.       GLfloat *buffer, *dst;
  466.       GLint elems_per_row;
  467.       GLint i, j, d;
  468.       elems_per_row = width * components;
  469.       buffer = (GLfloat *) malloc( height * elems_per_row * sizeof(GLfloat) * depth);
  470.       if (!buffer) {
  471.          return NULL;
  472.       }
  473.  
  474.       dst = buffer;
  475.       /**      img_pixels= pixels;*/
  476.       for (d=0; d<depth; d++) {
  477.          for (i=0;i<height;i++) {
  478.             GLvoid *src = gl_pixel_addr_in_image( &ctx->Unpack, pixels,
  479.                                                   width, height,
  480.                                                   srcFormat, srcType,
  481.                                                   d, i, 0 );
  482.             if (!src) {
  483.                free(buffer);
  484.                return NULL;
  485.             }
  486.  
  487.             switch (srcType) {
  488.                case GL_UNSIGNED_BYTE:
  489.                   for (j=0;j<elems_per_row;j++) {
  490.                      *dst++ = (GLfloat) ((GLubyte*)src)[j];
  491.                   }
  492.                   break;
  493.                case GL_BYTE:
  494.                   for (j=0;j<elems_per_row;j++) {
  495.                      *dst++ = (GLfloat) ((GLbyte*)src)[j];
  496.                   }
  497.                   break;
  498.                case GL_UNSIGNED_SHORT:
  499.                   if (ctx->Unpack.SwapBytes) {
  500.                      for (j=0;j<elems_per_row;j++) {
  501.                         GLushort value = ((GLushort*)src)[j];
  502.                         value = ((value >> 8) & 0xff) | ((value&0xff) << 8);
  503.                         *dst++ = (GLfloat) value;
  504.                      }
  505.                   }
  506.                   else {
  507.                      for (j=0;j<elems_per_row;j++) {
  508.                         *dst++ = (GLfloat) ((GLushort*)src)[j];
  509.                      }
  510.                   }
  511.                   break;
  512.                case GL_SHORT:
  513.                   if (ctx->Unpack.SwapBytes) {
  514.                      for (j=0;j<elems_per_row;j++) {
  515.                         GLshort value = ((GLshort*)src)[j];
  516.                         value = ((value >> 8) & 0xff) | ((value&0xff) << 8);
  517.                         *dst++ = (GLfloat) value;
  518.                      }
  519.                   }
  520.                   else {
  521.                      for (j=0;j<elems_per_row;j++) {
  522.                         *dst++ = (GLfloat) ((GLshort*)src)[j];
  523.                      }
  524.                   }
  525.                   break;
  526.                case GL_UNSIGNED_INT:
  527.                   if (ctx->Unpack.SwapBytes) {
  528.                      GLuint value;
  529.                      for (j=0;j<elems_per_row;j++) {
  530.                         value = ((GLuint*)src)[j];
  531.                         value = ((value & 0xff000000) >> 24)
  532.                               | ((value & 0x00ff0000) >> 8)
  533.                               | ((value & 0x0000ff00) << 8)
  534.                               | ((value & 0x000000ff) << 24);
  535.                         *dst++ = (GLfloat) value;
  536.                      }
  537.                   }
  538.                   else {
  539.                      for (j=0;j<elems_per_row;j++) {
  540.                         *dst++ = (GLfloat) ((GLuint*)src)[j];
  541.                      }
  542.                   }
  543.                   break;
  544.                case GL_INT:
  545.                   if (ctx->Unpack.SwapBytes) {
  546.                      GLint value;
  547.                      for (j=0;j<elems_per_row;j++) {
  548.                         value = ((GLint*)src)[j];
  549.                         value = ((value & 0xff000000) >> 24)
  550.                               | ((value & 0x00ff0000) >> 8)
  551.                               | ((value & 0x0000ff00) << 8)
  552.                               | ((value & 0x000000ff) << 24);
  553.                         *dst++ = (GLfloat) value;
  554.                      }
  555.                   }
  556.                   else {
  557.                      for (j=0;j<elems_per_row;j++) {
  558.                         *dst++ = (GLfloat) ((GLint*)src)[j];
  559.                      }
  560.                   }
  561.                   break;
  562.                case GL_FLOAT:
  563.                   if (ctx->Unpack.SwapBytes) {
  564.                      GLint value;
  565.                      for (j=0;j<elems_per_row;j++) {
  566.                         value = ((GLuint*)src)[j];
  567.                         value = ((value & 0xff000000) >> 24)
  568.                               | ((value & 0x00ff0000) >> 8)
  569.                               | ((value & 0x0000ff00) << 8)
  570.                               | ((value & 0x000000ff) << 24);
  571.                         *dst++ = *((GLfloat*) &value);
  572.                      }
  573.                   }
  574.                   else {
  575.                      MEMCPY( dst, src, elems_per_row*sizeof(GLfloat) );
  576.                      dst += elems_per_row;
  577.                   }
  578.                   break;
  579.                default:
  580.                   abort();
  581.             } /*switch*/
  582.          } /* for height */
  583.       } /*for*/
  584.  
  585.       image = (struct gl_image *) malloc( sizeof(struct gl_image) );
  586.       if (image) {
  587.          image->Width = width;
  588.          image->Height = height;
  589.          image->Depth = depth;  
  590.          image->Components = components;
  591.          image->Format = srcFormat;
  592.          image->Type = GL_FLOAT;
  593.          image->Interleaved = GL_FALSE;
  594.          image->Data = buffer;
  595.       }
  596.       else {
  597.          free( buffer );
  598.          return NULL;
  599.       }
  600.       return image;
  601.    }
  602.    else {
  603.       abort();
  604.    }
  605.    return NULL;  /* never get here */
  606. }
  607.  
  608.  
  609.  
  610. void gl_free_image( struct gl_image *image )
  611. {
  612.    if (image->Data) {
  613.       free(image->Data);
  614.    }
  615.    free(image);
  616. }
  617.